package com.jinyun.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.jinyun.pojo.ElectronicFence;
import com.jinyun.pojo.User;
import com.jinyun.pojo.Vehicle;
import com.jinyun.utils.PolygonUtils;
import com.jinyun.vo.ErrorResult;
import com.jinyun.vo.PageResult;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ElectronicFenceService {

    @Autowired
    private MongoTemplate mongoTemplate;



    /**
     * 新增电子围栏
     *
     * @param electronicFence
     * @return
     */
    public Object createElectronicFence(ElectronicFence electronicFence) {
        //对数据做校验
        if (StrUtil.isEmpty(electronicFence.getName()) || CollUtil.isEmpty(electronicFence.getMutiPoints())) {
            return ErrorResult.builder()
                    .errCode("500")
                    .errMessage("电子围栏的名称或多边形的坐标为空！").build();
        }

        electronicFence.setCreated(System.currentTimeMillis());
        this.mongoTemplate.save(electronicFence);

        return null;
    }

    /**
     * 电子围栏分页列表
     *
     * @param page
     * @param pageSize
     * @return
     */
    public Object queryElectronicFencePage(Integer page, Integer pageSize) {
        PageResult pageResult = new PageResult();
        pageResult.setPageNum(page);
        pageResult.setPagesize(pageSize);

        //分页查询数据
        PageRequest pageRequest = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.desc("created")));

        List<ElectronicFence> electronicFenceList = this.mongoTemplate.find(new Query().with(pageRequest), ElectronicFence.class);
        pageResult.setItems(electronicFenceList);

        return pageResult;
    }

    /**
     * 电子围栏列表
     *
     * @return
     */
    public Object queryElectronicFenceAll() {
        List<ElectronicFence> electronicFenceList = this.mongoTemplate.find(new Query().with(Sort.by(Sort.Order.desc("created"))), ElectronicFence.class);
        if (CollUtil.isEmpty(electronicFenceList)) {
            return Collections.emptyList();
        }
        return electronicFenceList.stream()
                .map(electronicFence -> MapUtil.builder()
                        .put("id", electronicFence.getId().toString())
                        .put("name", electronicFence.getName()).build())
                .collect(Collectors.toList());
    }

    /**
     * 根据id查询电子围栏数据
     *
     * @param id
     * @return
     */
    public Object queryElectronicFenceById(String id) {
        return this.mongoTemplate.findById(new ObjectId(id), ElectronicFence.class);
    }

    /**
     * 更新电子围栏
     *
     * @param id
     * @param electronicFence
     * @return
     */
    public Object updateElectronicFence(String id, ElectronicFence electronicFence) {
        //更新MongoDB中的数据
        Query query = Query.query(Criteria.where("id").is(new ObjectId(id)));
        Update update = Update.update("name", electronicFence.getName())
                .set("mutiPoints", electronicFence.getMutiPoints());

        UpdateResult updateResult = this.mongoTemplate.updateFirst(query, update, ElectronicFence.class);
        if (updateResult.getModifiedCount() == 1) {
            return null;
        }

        return ErrorResult.builder()
                .errCode("501")
                .errMessage("更新MongoDB电子围栏失败！").build();
    }

    /**
     * 根据id删除电子围栏
     *
     * @param id
     * @return
     */
    public Object deleteElectronicFence(String id) {
        //根据id查询电子围栏数据
        ElectronicFence oldElectronicFence = (ElectronicFence) this.queryElectronicFenceById(id);

        //删除MongoDB中的电子围栏数据
        Query query = Query.query(Criteria.where("id").is(new ObjectId(id)));
        DeleteResult deleteResult = this.mongoTemplate.remove(query, ElectronicFence.class);
        if (deleteResult.getDeletedCount() == 1) {
            return null;
        }

        return ErrorResult.builder()
                .errCode("501")
                .errMessage("删除MongoDB电子围栏失败！").build();
    }


    /**
     * 根据ID查询电子围栏并判断给定的经纬度是否在其范围内
     *
     * @param id   电子围栏的唯一标识符
     * @param lat  经纬度中的纬度
     * @param lng  经纬度中的经度
     * @return 如果点在电子围栏内，则返回true；否则返回false。
     */
    public boolean checkPointInFence(String id, String lat, String lng) {
        // 查询电子围栏
        Query query = new Query(Criteria.where("id").is(id));
        ElectronicFence fence = mongoTemplate.findOne(query, ElectronicFence.class);

        if (fence == null || fence.getMutiPoints() == null || fence.getMutiPoints().isEmpty()) {
            return false;
        }

        // 使用工具方法检查点是否在多边形内
        return PolygonUtils.isPointInPolygon(lat, lng, fence.getMutiPoints());
    }

}
